package aeolus.wind.spider.web.controller;

import java.awt.Font;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.SpiderWebPlot;
import org.jfree.chart.title.LegendTitle;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.RectangleEdge;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import aeolus.wind.spider.biz.dataobject.AbilityPackage;
import aeolus.wind.spider.biz.dataobject.Identity;
import aeolus.wind.spider.biz.dataobject.Vote;
import aeolus.wind.spider.biz.service.interfaces.AbilityService;
import aeolus.wind.spider.biz.service.interfaces.VoteService;
import aeolus.wind.spider.web.commons.BaseController;
import aeolus.wind.spider.web.commons.Constants;
import aeolus.wind.spider.web.commons.ability.AbilityPackageItem;
import aeolus.wind.spider.web.commons.spider.DrawSpider;
import aeolus.wind.spider.web.commons.spider.MaxInGroup;
import aeolus.wind.spider.web.commons.spider.SomeBody;
import aeolus.wind.spider.web.commons.spider.SomeGroup;

@Controller
public class SpiderController extends BaseController {

    @Autowired
    VoteService    voteService;
    @Autowired
    AbilityService abilityService;

    @RequestMapping("/seeMyself.htm")
    public String seeMyself(String identityName, boolean isAsUser, boolean isNotHiddenValue, ModelMap model)
                                                                                                            throws Exception {
        if (identityName == null) {
            identityName = getLoginName();
        }
        if (checkLogin() && checkCanSee(identityName)) {
            String ownerName = null;// 本次查看的所属负责人
            if (isAsUser) {
                // 得到领导者所在团队的相关结果
                ownerName = getLeaderName();
            } else if (checkCanLeadGroup()) {
                // 得到自己团队的的相关结果
                ownerName = getLoginName();
            }
            List<AbilityPackage> abilityPackageList = abilityService.listAbilityPackages(ownerName);
            model.addAttribute("abilityPackageList", abilityPackageList);
            model.addAttribute("identityName", getEncodedString(identityName));
        }
        model.addAttribute("isNotHiddenValue", isNotHiddenValue);
        return getScreen("seeMyself");
    }

    /**
     * 如果是不是我自己也不是我的下属，则不渲染页面
     * 
     * @param identityName
     * @return
     */
    private boolean checkCanSee(String identityName) {
        if (checkMyself(identityName) || checkIsLeadedByMe(identityName)) {
            return true;
        }
        return false;
    }

    @RequestMapping("/me.chart")
    public void me(String identityName, String abilityPackageId, boolean isShowMe, boolean isShowMeInOther,
                   boolean isShowGroupMax, boolean isShowGroupAve, boolean isNotHiddenValue, ModelMap model,
                   OutputStream stream) throws Exception {
        if (StringUtils.isBlank(identityName) || abilityPackageId == null || !checkCanSee(identityName)) return;
        // identityName = getUtfString(identityName);
        AbilityPackage abPackage = abilityService.findAbilityPackage(abilityPackageId);
        if (abPackage == null) return;

        JFreeChart chart = generateMeChart(identityName, abPackage, isShowMe, isShowMeInOther, isShowGroupMax,
                                           isShowGroupAve, isNotHiddenValue);
        ChartUtilities.writeChartAsPNG(stream, chart, 750, 400);
    }

    private JFreeChart generateMeChart(String identityName, AbilityPackage abPackage, boolean isShowMe,
                                       boolean isShowMeInOther, boolean isShowGroupMax, boolean isShowGroupAve,
                                       boolean isNotHiddenValue) {

        Set<String> abilitySet = new AbilityPackageItem(abilityService, abPackage).getAbilityNameSet();
        List<Identity> identities = identityService.listIdentitiesLeaded(abPackage.getOwnIdentityName());// 同组所有成员的列表
        SomeBody mySelf = new SomeBody(identityName);// 自我
        SomeGroup ourGroup = new SomeGroup();// 团队
        // 初始化团队和自我
        for (Identity identity : identities) {
            SomeBody sb = makeSomeBody(identity.getName(), abPackage.getOwnIdentityName(), abilitySet);
            ourGroup.addMember(sb);
            if (sb.getIdentityName().equals(identityName)) {
                mySelf = sb;
            }
        }
        DefaultCategoryDataset date = createMe(mySelf, ourGroup, isShowMe, isShowMeInOther, isShowGroupMax,
                                               isShowGroupAve, isNotHiddenValue);
        // 开始绘蛛网图
        SpiderWebPlot spiderwebplot;
        if (isNotHiddenValue) {
            // 全部显示
            spiderwebplot = new DrawSpider(date);
            spiderwebplot.setMaxValue(Constants.MAX_VALUE);
        } else {
            // 隐藏部分数值
            spiderwebplot = new SpiderWebPlot(date);
        }
        JFreeChart jfreechart = new JFreeChart(identityName + ":" + abPackage.getPackageName(),
                                               new Font("隶书", Font.BOLD, 20), spiderwebplot, false);
        LegendTitle legendtitle = new LegendTitle(spiderwebplot);

        legendtitle.setPosition(RectangleEdge.BOTTOM);
        jfreechart.addSubtitle(legendtitle);
        // 柱状图，暂不开放
        // JFreeChart jfreechart = ChartFactory.createBarChart(identityName + ":" + abilityType.getDescribtion(),
        // "能力名",
        // "得分",
        // createMe(mySelf, ourGroup, isShowMe, isShowMeInOther,
        // isShowGroupMax, isShowGroupAve),
        // PlotOrientation.VERTICAL, false, false, false);
        return jfreechart;
    }

    private DefaultCategoryDataset createMe(SomeBody mySelf, SomeGroup ourGroup, boolean isShowMe,
                                            boolean isShowMeInOther, boolean isShowGroupMax, boolean isShowGroupAve,
                                            boolean isNotHiddenValue) {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        Map<String, String> abilityWithId = getAbilityWithId(ourGroup);
        String anyAbName = getAnyAbName(abilityWithId);

        if (isShowMe && mySelf.getMe().size() > 0) {
            for (Entry<String, Double> entry : mySelf.getMe().entrySet()) {
                dataset.addValue(entry.getValue(), "自我认知", flushAbName(entry.getKey(), abilityWithId));
            }
        } else {
            // 这段为了保证图片颜色不会因为减少列而变化
            dataset.addValue(Constants.UNDIFINED_VALUE, "自我认知", anyAbName);
        }

        if (isShowMeInOther && mySelf.getMeInOther().size() > 0) {
            for (Entry<String, Double> entry : mySelf.getMeInOther().entrySet()) {
                dataset.addValue(entry.getValue(), "他人认知", flushAbName(entry.getKey(), abilityWithId));
            }
        } else {
            dataset.addValue(Constants.UNDIFINED_VALUE, "他人认知", anyAbName);
        }

        // 这两组数值默认不出现
        if (isNotHiddenValue) {
            if (isShowGroupMax && ourGroup.getGroupMax().size() > 0) {
                for (Entry<String, Double> entry : ourGroup.getGroupMax().entrySet()) {
                    dataset.addValue(entry.getValue(), "团队最大值", flushAbName(entry.getKey(), abilityWithId));
                }
            } else {
                dataset.addValue(Constants.UNDIFINED_VALUE, "团队最大值", anyAbName);
            }

            if (isShowGroupAve && ourGroup.getGroupAve().size() > 0) {
                for (Entry<String, Double> entry : ourGroup.getGroupAve().entrySet()) {
                    dataset.addValue(entry.getValue(), "团队平均值", flushAbName(entry.getKey(), abilityWithId));
                }
            } else {
                dataset.addValue(Constants.UNDIFINED_VALUE, "团队平均值", anyAbName);
            }
        }
        return dataset;
    }

    private Map<String, String> getAbilityWithId(SomeGroup ourGroup) {
        Map<String, MaxInGroup> abilityWithMaxInGroup = ourGroup.getMaxInGroup();
        Map<String, String> abilityWithId = new HashMap<String, String>();
        for (Entry<String, MaxInGroup> entry : abilityWithMaxInGroup.entrySet()) {
            abilityWithId.put(entry.getKey(), entry.getValue().getAbNameWithNameList());
        }
        return abilityWithId;
    }

    private String getAnyAbName(Map<String, String> abilityWithId) {
        for (Entry<String, String> entry : abilityWithId.entrySet()) {
            return entry.getValue();
        }
        return "";// 理论上这是不可能的
    }

    private String flushAbName(String abilityName, Map<String, String> abilityWithId) {
        String nameList = abilityWithId.get(abilityName);
        if (StringUtils.isNotBlank(nameList)) return nameList;
        return abilityName;
    }

    private SomeBody makeSomeBody(String identityName, String ownerName, Set<String> abilitySet) {
        List<Vote> voteList = voteService.listVoted(ownerName, identityName);
        SomeBody sb = new SomeBody(identityName);

        for (Vote vote : voteList) {
            if (abilitySet.contains(vote.getAbilityName())) {
                if (identityName.equals(vote.getIdentityNameVote())) {
                    sb.addAbilityByMe(vote.getAbilityName(), Double.valueOf(vote.getValue()));
                } else {
                    sb.addAbilityByOther(vote.getAbilityName(), Double.valueOf(vote.getValue()));
                }
            }
        }
        return sb;
    }
}
